<?php
include_once __DIR__ . "/../base.php";
class tlhsb extends base
{
    // protected $xml;
    // protected $head;

    // protected $channel_type = "WX";

    // protected $appid;

    // protected $IsvOrgId;


    // protected $provider_type;


    protected $sign_type = "";
    protected $appid = "";

    protected $md5_key = "";
    protected $publicKey = "";
    protected $privateKey = "";
    protected $cusid = "";
    // protected $merchant_id = "";




    public function __construct($setting)
    {
        $this->sign_type = $setting['sign_type'];
        $this->appid = $setting['appid'];  //appid
        // $this->merchant_id = $setting['merchant_id'];  //merchant_id
        $this->callback_url = $setting['callback_url'] ?? "";
        $this->privateKey = $setting['privateKey'] ?? "";
        $this->publicKey = $setting['publicKey'] ?? "";
        $this->cusid = $setting['cusid'] ?? "";

        // $this->md5_key = $setting['md5_key'] ?? "";
    }


    // 提交支付
    public function submitOrder($data)
    {
        $url = "https://vsp.allinpay.com/apiweb/unitorder/pay";
        $order = [
            "cusid" => $this->cusid,
            "appid" => $this->appid,
            'body'             => $data['OutTradeNo'],
            'version'             => 11,
            'reqsn'     => $data['OutTradeNo'],
            'trxamt'        => $data['TotalAmount'], // 单位：分
            'paytype'        => "W06", // W06小程序 W02微信js
            'randomstr' => $this->getRandomString(),
            "notify_url" => $this->callback_url,
            'sub_appid' => $data['SubAppId'],
            "signtype" => 'RSA',
            'acct' => $data['OpenId'],
        ];

        // $file_name = $_SERVER['DOCUMENT_ROOT'] . "/../api_resource/logs/" . date('Ymd') . "_pay.log";

        // file_put_contents($file_name, date('Y-m-d H:i:s') . "--------swt111请求报文：---------", FILE_APPEND);
        // file_put_contents($file_name, "\r\n", FILE_APPEND);
        // file_put_contents($file_name, "md5", FILE_APPEND);
        // file_put_contents($file_name, "\r\n", FILE_APPEND);
        $order['sign'] = urlencode($this->getSign($order));
        // $order_xml = $this->ToXml($order);
        $paramsStr = $this->ToUrlParams($order);
        // $paramsStr = http_build_query($order);
        // var_dump($paramsStr);
        $headerArray = array("Content-type:application/x-www-form-urlencoded", "Accept:application/json");
        $res_str = $this->request($url, ($paramsStr));
        // $res_str = $this->httpRequest($url, "POST", json_encode($paramsStr), "", "", $headerArray);

        $response_arr = json_decode($res_str, true);
        $file_name = $_SERVER['DOCUMENT_ROOT'] . "/../api_resource/logs/" . date('Ymd') . "_pay.log";

        file_put_contents($file_name, date('Y-m-d H:i:s') . "--------tlhsb请求报文：---------", FILE_APPEND);
        file_put_contents($file_name, "\r\n", FILE_APPEND);
        file_put_contents($file_name, json_encode($order), FILE_APPEND);
        file_put_contents($file_name, "\r\n", FILE_APPEND);


        file_put_contents($file_name, date('Y-m-d H:i:s') . "--------tlhsb响应报文：---------", FILE_APPEND);
        file_put_contents($file_name, "\r\n", FILE_APPEND);
        file_put_contents($file_name, json_encode($response_arr), FILE_APPEND);
        file_put_contents($file_name, "\r\n", FILE_APPEND);
        if (!$this->verifySign($response_arr)) {
            return ['status' => 0, 'msg' => "验证失败:"];
        }

        if ($response_arr['retcode'] == "SUCCESS") {
            if ($response_arr['trxstatus'] == 0000) {
                $json = json_decode($response_arr['payinfo'], true);
                // 处理时间 timeStamp
                $json['timestamp'] = $json['timeStamp'];
                return array('status' => 1, 'payInfo' => $json);
            } else {
                return ['status' => 0, 'msg' => "下单失败:" . $response_arr['errmsg']];
            }
        } else {
            if (isset($response_arr['retcode'])) {
                return ['status' => 0, 'msg' => "下单失败:" . $response_arr['retmsg']];
            }
        }
    }
    public function ToUrlParams(array $array)
    {
        $buff = "";
        foreach ($array as $k => $v) {
            if ($v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }
    public function getSign($array)
    {
        ksort($array);
        $bufSignSrc = $this->ToUrlParams($array);
        $private_key = $this->privateKey;
        $private_key = chunk_split($private_key, 64, "\n");
        $key = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($private_key) . "-----END RSA PRIVATE KEY-----";
        // echo $bufSignSrc;
        if (openssl_sign($bufSignSrc, $signature, $key)) {
        } else {
            echo 'sign fail';
        }
        $sign = base64_encode($signature); //加密后的内容通常含有特殊字符，需要编码转换下，在网络间通过url传输时要注意base64编码是否是url安全的
        return $sign;
    }
    public function verifySign($array)
    {
        $sign = $array['sign'];
        unset($array['sign']);
        ksort($array);
        $bufSignSrc = $this->ToUrlParams($array);
        // var_dump($bufSignSrc);

        $public_key = $this->publicKey;
        $public_key = chunk_split($public_key, 64, "\n");
        $key = "-----BEGIN PUBLIC KEY-----\n$public_key-----END PUBLIC KEY-----\n";
        $result = openssl_verify($bufSignSrc, base64_decode($sign), $key);
        // var_dump($key);
        // var_dump($result);
        return $result;
        // $key = preg_replace('/(.{64})/', "$1\n", $this->publicKey);
        // $public_key = '-----BEGIN PUBLIC KEY-----' . "\n" . $key . "\n" . '-----END PUBLIC KEY-----';
        // $signPars = "";
        // ksort($arr);
        // foreach ($arr as $k => $v) {
        //     if ("sign" != $k && "" != $v) {
        //         $signPars .= $k . "=" . $v . "&";
        //     }
        // }
        // $signPars = substr($signPars, 0, strlen($signPars) - 1);
        // var_dump($signPars);
        // $res = openssl_get_publickey($public_key);
        // $result = (bool)openssl_verify($signPars, base64_decode($arr['sign']), $res);
        // var_dump($result);
        // if ($result == 1) {
        //     return $arr["sign"];
        // }
    }

    // 回调
    public function notifyOrder($params)
    {
        $resData = [
            'code' => 200,
            "data" => [],
            "msg" => "",
            "resp" => 'fail'
        ];

        // 验证签名
        if ($this->verifySign($params)) {
            if ($params['trxstatus'] == 0000) {
                $resData["data"] = [
                    "order_sn" =>  $params['cusorderid'],
                ];
                $resData["resp"] = "success";
            } else {
                $resData['code'] = 500;
                $resData['msg'] = "交易失败,";
            }
        } else {
            $resData['code'] = 500;
            $resData['msg'] = "签名不匹配,解密签名:" .  ",请求签名:" . $params['sign'];
        }
        $resData["data"] = [
            "order_sn" =>  $params['cusorderid'],
        ];
        // if ($sign != $swiftpassSign) {

        // } else if ($parameters['status'] == 0 && $parameters['result_code'] == 0) {

        // }
        return $resData;
    }
    public function refund($order_sn, $refund_order_sn, $refund_price, $remark)
    {
        $url = "https://vsp.allinpay.com/apiweb/tranx/refund";
        $refund_post_data = [
            'cusid' => $this->cusid,
            'appid' => $this->appid,
            'version'             => 11,
            'trxamt' => $refund_price,
            'reqsn'           => $refund_order_sn,
            'oldreqsn'        => $order_sn, // 单位：分
            'signtype'         => "RSA",       // 你也可以在下单时单独设置来想覆盖它
            'randomstr' => $this->getRandomString(),
        ];
        $refund_post_data['sign'] = urlencode($this->getSign($refund_post_data)); //签名  

        $paramsStr = $this->ToUrlParams($refund_post_data);



        $file_name = $_SERVER['DOCUMENT_ROOT'] . "/../api_resource/logs/" . date('Ymd') . "_pay.log";

        file_put_contents($file_name, date('Y-m-d H:i:s') . "--------tlhsb退款请求报文：---------", FILE_APPEND);
        file_put_contents($file_name, "\r\n", FILE_APPEND);
        file_put_contents($file_name, json_encode($refund_post_data), FILE_APPEND);
        file_put_contents($file_name, "\r\n", FILE_APPEND);

        // $rsp = request($url, $paramsStr);
        $res = $this->httpRequest($url, 'POST', $paramsStr, '', '', array("content-type: application/x-www-form-urlencoded;charset=UTF-8"));
        $rsp_arr = json_decode($res, true);
        // file_put_contents(RUNTIME_PATH . "swift_back_" . date("Ymd") . ".txt", "post_data:" . print_r($refund_post_data, 1) . "\n return_data:" . print_r($response_arr, 1), FILE_APPEND);
        file_put_contents($file_name, date('Y-m-d H:i:s') . "--------tlhsb退款返回报文：---------", FILE_APPEND);
        file_put_contents($file_name, "\r\n", FILE_APPEND);
        file_put_contents($file_name, json_encode($rsp_arr), FILE_APPEND);
        file_put_contents($file_name, "\r\n", FILE_APPEND);
        $data = [
            "code" => 500,
            "data" => [],
            "msg" =>  ''
        ];
        if ($rsp_arr['retcode'] == 'FAIL') {
            $data['msg'] = $rsp_arr['retmsg'];
            return $data;
        }
        if (!$this->verifySign($rsp_arr)) {
            // echo "验签正确,进行业务处理";
            $data['msg'] = "验证签名失败";
            return $data;
        }
        if (is_array($rsp_arr)) {
            // $result = [];
            //                file_put_contents(RUNTIME_PATH."swift_back_".date("Ymd").".txt","\n return_obj:".print_r($result,1),FILE_APPEND);
            if ($rsp_arr['retcode'] == "SUCCESS" && $rsp_arr['trxstatus'] == "0000") {
                $data['code'] = 200;
            } else {
                $data['msg'] = $rsp_arr['retmsg'];
            }
        }
        return $data;
    }
    public function MakeSign_swift_rsa_callback($arr)
    {

        $key = preg_replace('/(.{64})/', "$1\n", $this->publicKey);
        $public_key = '-----BEGIN PUBLIC KEY-----' . "\n" . $key . "\n" . '-----END PUBLIC KEY-----';

        $signPars = "";
        ksort($arr);
        foreach ($arr as $k => $v) {
            if ("sign" != $k && "" != $v) {
                $signPars .= $k . "=" . $v . "&";
            }
        }
        //            file_put_contents(RUNTIME_PATH."swift_rsa1.txt","arr:\n".json_encode($arr)."\n",FILE_APPEND);
        //            file_put_contents(RUNTIME_PATH."swift_rsa1.txt","public_key:\n".$public_key."\n",FILE_APPEND);
        //            file_put_contents(RUNTIME_PATH."swift_rsa1.txt","sign_str:\n".$signPars."\n",FILE_APPEND);

        $signPars = substr($signPars, 0, strlen($signPars) - 1);
        $res = openssl_get_publickey($public_key);
        if ($this->sign_type == 'RSA_1_1') {
            $result = (bool)openssl_verify($signPars, base64_decode($arr['sign']), $res);
            openssl_free_key($res);
        } else if ($this->sign_type == 'RSA_1_256') {
            $result = (bool)openssl_verify($signPars, base64_decode($arr['sign']), $res, OPENSSL_ALGO_SHA256);
            openssl_free_key($res);
        }
        if ($result == 1) {
            return $arr["sign"];
        }
        return 'error';
    }

    public function getRandomString()
    {
        // mt_srand((float)microtime() * 10000); //optional for php 4.2.0 and up.
        $charid = strtoupper(md5(uniqid(rand(), true)));
        // $hyphen = chr(45); // "-"
        $uuid = substr($charid, 0, 8)
            . substr($charid, 8, 4)
            . substr($charid, 12, 4)
            . substr($charid, 16, 4)
            . substr($charid, 20, 12);
        return $uuid;
    }
    public function request($url, $params)
    {
        $ch = curl_init();
        $this_header = array("content-type: application/x-www-form-urlencoded;charset=UTF-8");
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this_header);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); //如果不加验证,就设false,商户自行处理
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

        $output = curl_exec($ch);
        curl_close($ch);
        return  $output;
    }
}
